/**
 * 
 */
package com.ibm.demoBankJSF.backend;

import com.ibm.demoBankJSF.base.*;
import java.sql.Connection;
import java.sql.Date;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.*;
/**
 * Clase con la que se accede a la base de datos 
 * @author Sergio Villegas, Javier Trapero y Ruben Ropero
 */

public class AccesoBD {

	/**
	 * obtiene un cliente de la base de datos en funcion del indentificador y el password
	 * return Retorna un cliente
	 * @throws SQLException 
	 */
	public static Cliente loginCliente(String identificador, String password) throws SQLException{
		Connection conn = Conexion.getConnection();
		Statement s = conn.createStatement(); 
		
		String sql = "SELECT * FROM cliente WHERE nif = '" + identificador + "' AND password = '" + password + "'";
		ResultSet rs = s.executeQuery(sql);

		Cliente cliente = null;
		if (rs != null){
			while (rs.next()){
				String nombre, apellidos, direccion, ciudad, estado, cp, telefono, movil, email;
				int idCliente;
				idCliente = rs.getInt("cliente_id");
				nombre = rs.getString("nombre");
				apellidos = rs.getString("apellidos");
				direccion = rs.getString("direccion");
				ciudad = rs.getString("ciudad");
				estado = rs.getString("estado");
				cp = rs.getString("codPostal");
				telefono = rs.getString("telefono");
				movil = rs.getString("movil");
				email = rs.getString("email");

				cliente = new Cliente(idCliente, nombre, apellidos, identificador, password, telefono, movil, email,
						direccion, cp, ciudad, estado);
			}
		}
		rs.close();
		s.close();
		Conexion.putConnection(conn);
		return cliente;
	}

	/**
	 * obtiene las cuentas de un clientede la base de datos en funcion del id de cliente
	 * return retorna una lista de Cuentas
	 * @throws SQLException 
	 */
	public static List obtenerCuentas(int idCliente) throws SQLException{

		Connection conn = Conexion.getConnection();
		Statement s = conn.createStatement(); 
		ResultSet rs = s.executeQuery("SELECT * FROM cuenta c, cliente_cuenta cc " +
				"WHERE cc.cliente=" + idCliente + " AND c.cuenta_id=cc.cuenta");

		List listaCuentas = new ArrayList();
		Cuenta cuenta;
		String numeroCuenta, descripcion;
		int idCuenta;
		double saldo = 0;
		while (rs.next()){
			idCuenta = rs.getInt("cuenta_id");
			numeroCuenta = rs.getString("numero");
			descripcion = rs.getString("descripcion");
			saldo= rs.getDouble("saldo");	
			cuenta = new Cuenta(idCuenta, numeroCuenta, descripcion, saldo);
			listaCuentas.add(cuenta);
		}

		rs.close();
		s.close();
		Conexion.putConnection(conn);
		return listaCuentas;
	}

	/**
	 * obtiene el ultimo movimiento de una cuenta de la base de datos en funcion de la id de la cuenta
	 * return retorna un movimiento 
	 * @throws SQLException 
	 */
	public static MovCuenta obtenerUltimoMov(int idCuenta) throws SQLException{
		Connection conn = Conexion.getConnection();
		Statement s = conn.createStatement();
		String sql = "SELECT movimiento_id, concepto, fecha, fechaValor, remitente, importe, m.saldo " +
		"FROM movimiento m, cuenta c WHERE m.cuenta = c.cuenta_id  AND m.cuenta=" + idCuenta + " AND " +
		"movimiento_id=(SELECT MAX(movimiento_id) FROM movimiento m, cuenta c WHERE m.cuenta = c.cuenta_id AND m.cuenta=" + idCuenta + ")";
		ResultSet rs = s.executeQuery(sql);
		MovCuenta movimiento = null;
		int idMovimiento;
		String concepto, remitente;
		Date fecha, fechaValor;
		double importe, saldo;

		if (rs != null){
			while (rs.next()){
				idMovimiento = rs.getInt("movimiento_id");
				concepto = rs.getString("concepto");
				fecha = rs.getDate("fecha");
				fechaValor = rs.getDate("fechaValor");
				remitente = rs.getString("remitente");
				importe = rs.getDouble("importe");
				saldo = rs.getDouble("saldo");
				movimiento = new MovCuenta(idMovimiento, concepto, fecha, fechaValor, remitente, importe, saldo);
			}
		}

		rs.close();
		s.close();
		Conexion.putConnection(conn);
		return movimiento;
	}	

	/**
	 * obtiene el ultimo id de la tabla de movimientos
	 * return retorna un movimiento 
	 * @throws SQLException 
	 */
	public static int obtenerUltimoIdMov() throws SQLException{
		Connection conn = Conexion.getConnection();
		Statement s = conn.createStatement(); 
		String sql = "SELECT MAX(movimiento_id) as movimiento_id FROM movimiento";
		ResultSet rs = s.executeQuery(sql);
		int idMovimiento = 0;

		if (rs != null){
			while (rs.next()){
				idMovimiento = rs.getInt("movimiento_id");
			}
		}

		rs.close();
		s.close();
		Conexion.putConnection(conn);
		return idMovimiento;
	}	

	/**
	 * obtiene una lista de movimientos en funcion de unos parametros, de la base de datos 
	 * return Retorna una lista de movimientos
	 * @throws SQLException 
	 */
	public static List consultarMovimientos(String numCuenta, java.util.Date fechaInicial, java.util.Date fechaFinal, int numeroDias, double cantidadDesde, double cantidadHasta) throws SQLException{
		Connection conn = Conexion.getConnection();
		Statement s = conn.createStatement();
		String sql = "SELECT m.movimiento_id, m.concepto, m.remitente, m.fecha, m.fechaValor, m.importe, m.saldo FROM cuenta c, movimiento m " +
		" WHERE c.cuenta_id = m.cuenta AND c.numero = '" + numCuenta + "'";

		if ((fechaFinal != null) && (fechaInicial != null)){
			sql = sql + " AND m.fecha >= '" + convertDatetoSQLDate(fechaInicial) + "' AND m.fecha <= '" + convertDatetoSQLDate(fechaFinal) + "'";
		}
		else if (fechaInicial != null){
			sql = sql + " AND m.fecha = '" + convertDatetoSQLDate(fechaInicial) + "'";
		}

		else if (numeroDias > 0){
			Date fechaConsulta = fechaMenos(convertDatetoSQLDate(new java.util.Date()),numeroDias);
			sql = sql + " AND m.fecha >= '" + fechaConsulta + "'";
		}

		if (cantidadDesde > 0){
			sql = sql + " AND m.importe >= " + cantidadDesde;
		}

		if (cantidadHasta > 0){
			sql = sql + " AND m.importe <= " + cantidadHasta;
		}
		
		sql = sql + " ORDER BY m.movimiento_id DESC";

		ResultSet rs = s.executeQuery(sql);

		List listaMovimientos = new ArrayList();
		if (rs != null){
			MovCuenta movimiento;
			int idMovimiento;
			String concepto, remitente;
			Date fecha, fechaValor;
			double importe, saldo;

			while (rs.next()){
				idMovimiento = rs.getInt("movimiento_id");
				concepto = rs.getString("concepto");
				remitente = rs.getString("remitente");
				fecha = rs.getDate("fecha");
				fechaValor = rs.getDate("fechaValor");
				importe = rs.getDouble("importe");
				saldo = rs.getDouble("saldo");
				movimiento = new MovCuenta (idMovimiento, concepto, fecha, fechaValor, remitente, importe, saldo);
				listaMovimientos.add(movimiento);
			}			
		}
		rs.close();
		s.close();
		Conexion.putConnection(conn);
		return listaMovimientos;
	}


	/**
	 * obtiene los ultimos diez movimientos  de la base de datos 
	 * return Retorna una lista con los 10 ultimos movimientos
	 * @throws SQLException 
	 */
	public static List obtenerDiezUltimosMovimientos(int idCuenta) throws SQLException{
		Connection conn = Conexion.getConnection();
		Statement s = conn.createStatement(); 
		String sql = "SELECT  * FROM movimiento m WHERE  m.cuenta =" + idCuenta + "ORDER BY movimiento_id DESC";

		ResultSet rs = s.executeQuery(sql);

		List listaMovimientos = new ArrayList();
		if (rs != null){
			MovCuenta movimiento;
			int i = 0;
			while (rs.next() && (i < 10)){
				int idMovimiento = rs.getInt("movimiento_id");
				String concepto = rs.getString("concepto");
				String remitente = rs.getString("remitente");
				Date fecha = rs.getDate("fecha");
				Date fechaValor = rs.getDate("fechaValor");
				double importe = rs.getDouble("importe");
				double saldo = rs.getDouble("saldo");
				movimiento = new MovCuenta (idMovimiento, concepto, fecha, fechaValor, remitente, importe, saldo);
				listaMovimientos.add(movimiento);
				i++;
			}			
		}
		rs.close();
		s.close();
		Conexion.putConnection(conn);
		return listaMovimientos;
	}

	public static Cuenta obtenerCuenta (String numCuenta) throws SQLException{
		Connection conn = Conexion.getConnection();
		Statement s = conn.createStatement();
		String sql = "SELECT cuenta_id, numero, descripcion, saldo FROM cuenta WHERE numero = '" + numCuenta + "'";
		ResultSet rs = s.executeQuery(sql);
		Cuenta cuenta = null;
		if (rs != null){
			while (rs.next()){
				int idCuenta = rs.getInt("cuenta_id");		
				String numero = rs.getString("numero");
				String descripcion = rs.getString("descripcion");
				double saldo = rs.getDouble ("saldo");
				cuenta = new Cuenta(idCuenta, numero, descripcion, saldo);
			}		
		}
		rs.close();
		s.close();
		Conexion.putConnection(conn);
		return cuenta;
	}

	/**
	 * Realiza un movimiento en una cuenta
	 * @throws SQLException 
	 */
	public static void realizarMovimiento (int idMovimiento, String comentario, int idCuenta, java.util.Date fecha, java.util.Date fechaValor, String remitente, double importe, double saldo) throws SQLException{
		Connection conn = Conexion.getConnection();
		Statement s = conn.createStatement();
		String sql ="";
		if (remitente.equals("")){
			sql = "INSERT INTO movimiento(movimiento_id, concepto, cuenta, fecha, fechaValor, importe, saldo) " +
			"VALUES (" + idMovimiento + ", '" + comentario + "', " + idCuenta + ", '" + convertDatetoSQLDate(fecha) +"', '" + convertDatetoSQLDate(fechaValor) + "', " + importe + ", " + saldo +")";
		}
		else{
			sql = "INSERT INTO movimiento(movimiento_id, concepto, cuenta, fecha, fechaValor, remitente, importe, saldo) " +
			"VALUES (" + idMovimiento + ", '" + comentario + "', " + idCuenta + ", '" + convertDatetoSQLDate(fecha) +"', '" + convertDatetoSQLDate(fechaValor) + "', '" + remitente+ "', " + importe + ", " + saldo +")";
		}

		s.executeUpdate(sql);

		s.close();
		Conexion.putConnection(conn);
	}

	/**
	 * Actualiza el saldo de una cuenta
	 * @throws SQLException 
	 */
	public static void actualizarSaldo (int idCuenta, double saldo) throws SQLException{
		Connection conn = Conexion.getConnection();
		Statement s = conn.createStatement();

		String sql = "UPDATE cuenta SET saldo = " + saldo + " WHERE cuenta_id = " + idCuenta ;

		s.executeUpdate(sql);
		s.close();
		Conexion.putConnection(conn);
	}


	public static java.sql.Date convertDatetoSQLDate(java.util.Date fecha){

		java.sql.Date sqlDate =  new java.sql.Date(fecha.getTime());
		return sqlDate;

	}

	public static Date fechaMenos(java.util.Date fch, int dias){
		Calendar cal = new GregorianCalendar();
		cal.setTimeInMillis(fch.getTime());
		cal.add(Calendar.DATE, - dias);
		return new Date(cal.getTimeInMillis());
	} 
}



